Εάν δεν έχετε κατεβάσει και εγκαταστήσει στον Η/Υ σας την R και το R-Studio, παρακαλώ κάντε το τώρα. Επίσης, καλό θα ήταν να μην εγκαταστήσετε την νεότερη έκδοση της R (> 3.5), αλλά την παλαιότερη έκδοση της (3.4.4), καθώς προς το παρόν αρκετές βιβλιοθήκες (packages), μπορεί να εμφανίσουν προβλήματα συμβατότητας.
Ας ανοίξουμε το R-studio και ας δούμε από τι συνήθως αποτελείται:
Το πρώτο βήμα σε οποιαδήποτε ανάλυση θέλουμε να κάνουμε στην R και το R-studio είναι να οργανώσουμε τα αρχεία τα οποία είναι απαραίτητα για την ανάλυση που θέλουμε να κάνουμε, με τρόπο τέτοιο ώστε να είναι εύκολα διαθέσιμα και προσβάσιμα. Για αυτόν τον λόγο συνεπώς, θα δημιουργούμε κάθε φορά ένα project.
New Project, όπως φαίνεται στην εικόνα:New directory.New Project.Project.Πώς γίνεται αυτό;
Με την δημιουργία επιπλέον βιβλιοθηκών (libraries/packages1) που επιτελούν εξειδικευμένες λειτουργίες.
Αυτή τη στιγμή υπάρχουν περισσότερα από 10.000 ενεργές βιβλιοθήκες για την R.
Το σύνολο των βιβλιοθηκών που μπορεί κάποιος να χρησιμοποιήσει στην R βρίσκεται στον επίσημο ιστότοπο της R, καθώς και στο github, στο R-Forge και αλλού.
Η R έχει εγκατεστημένες κάποιες βασικές βιβλιοθήκες (base, datasets, utils, grDevices, graphics, stats, methods) και μπορούμε φυσικά να εγκαταστήσουμε όποια βιβλιοθήκη θέλουμε.
Πριν κάνουμε οτιδήποτε, πατήστε Ctl + Alt + N, ώστε να δημιουργήσετε ένα κενό αρχείο κώδικα (το πάνω αριστερά τμήμα της οθόνης σας):
Ακολούθως, πληκτρολογήστε Ctl + S, ώστε να αποθηκεύσετε το κενό αρχείο κώδικα με το όνομα Εισαγωγή στην R.
Στη συνέχεια πληκτρολογείστε την ακόλουθη εντολή:
.libPaths()Η R είναι case-sensitive, οπότε πρέπει να είμαστε εξαιρετικά προσεκτικοί όσον αφορά την πληκτρολόγηση οποιασδήποτε εντολής.
Εάν θέλουμε να κατεβάσουμε μια βιβλιοθήκη (E.g., την βιβλιοθήκη ονόματι easypackages) που βρίσκεται στο επίσημο καταθετήριο της R, τότε χρησιμοποιούμε την ακόλουθη εντολή:
## CRAN repository:
install.packages("easypackages", dependencies = TRUE)Προσέξετε ότι το όνομα της εκάστοτε βιβλιοθήκης πρέπει να είναι εντός εισαγωγικών
Κάντε το ίδιο για τις ακόλουθες βιβλιοθήκες:
1. tidyverse
2. xlsx
3. vegan
4. betapart
5. red
6. raster
7. magrittr
8. pacman
ΠΡΟΣΟΧΗ
Δεν χρειάζεται να εγκαταστήσουμε δεύτερη φορά την οποιαδήποτε βιβλιοθήκη για να την χρησιμοποιήσουμε. Το μόνο που χρειάζεται να κάνουμε είναι να φορτώσουμε την εκάστοτε βιβλιοθήκη στην R.
Εάν έχουμε εγκαταστήσει ήδη μια βιβλιοθήκη, μπορούμε να διαπιστώσουμε ποιά έκδοση της έχουμε και εάν χρειάζεται, να την αναβαθμίσουμε:
packageVersion("easypackages")## [1] '0.1.0'
Κάντε το ίδιο για τις βιβλιοθήκες που εγκαταστήσατε προηγουμένως.
update.packages("easypackages")Εάν θέλουμε να δούμε ποιές βιβλιοθήκες έχουμε εγκαταστήσει στον Η/Υ μας, μπορούμε να τρέξουμε την ακόλουθη εντολή:
installed.packages()Εάν για κάποιο λόγο δεν θυμόμαστε ποιές εντολές περιέχει μια βιβλιοθήκη και τι κάνουν αυτές οι εντολές, τοτέ πληκτρολογώντας την ακόλουθη εντολή, μπορούμε να αποκτήσουμε πρόσβαση στο εγχειρίδιο χρήσης της εκάστοτε βιβλιοθήκης:
help(package = "easypackages")Κάντε το ίδιο για την βιβλιοθήκη xlsx.
Ένας άλλος τρόπος - εάν δουλεύουμε στο R-Studio - είναι να πληκτρολογήσουμε το όνομα της βιβλιοθήκης που μας ενδιαφέρει (E.g., pacman) και ύστερα να πληκτρολογήσουμε δύο φορές : (E.g., pacman::). Δοκιμάστε με όποια βιβλιοθήκη θέλετε.
Χρησιμοποιώντας την ακόλουθη εντολή:
help.start()Εάν δεν γνωρίζουμε πώς ή τι κάνει μια εντολή μια συγκεκριμένης βιβλιοθήκης, τότε υπάρχουν 3 τρόποι για να το διαπιστώσουμε αυτό:
1. Μέσω του εγχειριδίου χρήσης της εκάστοτε βιβλιοθήκης2
2. Μέσω της ακόλουθης εντολής:
example("min", package = "base")3. Μέσω της εντολής:
`?`(min)Κάντε το ίδιο για μια εντολή από την βιβλιοθήκη red ή όποια άλλη βιβλιοθήκη επιθυμείτε.
Με την εντολή:
libraries("red", "raster")ή με την εντολή:
pacman::p_load(red, raster)Παρατηρείτε κάποια διαφορά μεταξύ των δύο εντολών;
Tip
Μπορούμε να πληκτρολογήσουμε easypackages::libraries('red', 'raster') εάν για οποιονδήποτε λόγο δεν θέλουμε να φορτώσουμε την βιβλιοθήκη easypackages.
Είναι εξαιρετικά χρήσιμο να γνωρίζουμε σε ποιόν φάκελο αποθηκεύει η R τα δεδομένα που προκύπτουν από την ανάλυση μας. Εάν έχουμε δημιουργήσει ένα project3, τότε αυτόματα η R θα αποθηκεύσει οτιδήποτε δημιουργήσουμε σε αυτόν τον φάκελο.
getwd()Έστω ότι θέλουμε να δημιουργήσουμε έναν νέο φάκελο για να αποθηκεύσουμε κάποιες εικόνες που έχουμε δημιουργήσει στην R. Τον φάκελο αυτό (που θέλουμε να τον ονομάσουμε Figures) τον δημιουργούμε με την ακόλουθη εντολή:
dir.create('./Figures)Προσέξτε ότι το τμήμα του κώδικα ./ υποδηλώνει ότι θέλουμε ο φάκελος να δημιουργηθεί εντός του κεντρικού φακέλου (working directory) στον οποίο εργαζόμαστε4.
Δημιουργήστε τώρα τρεις φακέλους, ως εξής:
1. Έναν φάκελο ονόματι Scripts
2. Έναν φάκελο ονόματι Data
3. Έναν φάκελο ονόματι RDS εντός του φακέλου Data.
##-------------------------
## The solution
##-------------------------
dir.create("./Scripts")
dir.create("./Data")
dir.create("./Data/RDS")Εάν θέλουμε να αλλάξουμε τον φάκελο στον οποίο θα αποθηκεύσουμε κάτι, αυτό γίνεται με την ακόλουθη εντολή:
## Don't run it
setwd("./Scripts")Στην πραγματικότητα αυτή η εντολή αλλάζει το workind directory5. Θα δούμε παρακάτω πώς μπορούμε στην πραγματικότητα να αποθηκεύσουμε κάποια δεδομένα που δημιουργήσαμε εντός της R σε άλλον φάκελο από το working directory.
Αρκετά συχνά6 θα εμφανίζεται κάποιο σφάλμα στην R σχετικά με μια εντολή που επιθυμούμε να τρέξουμε. Τις περισσότερες φορές7 θα είμαστε σε θέση να αναγνωρίσουμε μόνοι μας το σφάλμα και να το επιλύσουμε. Κάποιες φορές όμως, μπορεί να χρειαστούμε βοήθεια. Ευτυχώς για εμάς, πολλοί άλλοι χρήστες θα έχουν έρθει αντιμέτωποι με το ίδιο πρόβλημα και θα έχουν ανεβάσει σε κάποιον από τους ακόλουθους ιστότοπους την λύση του προβλήματος:
1. R-seek
2. R-bloggers
3. Stack-exchange
4. Stack-overflow
5. R-project search
Και φυσικά ο πιο εύκολος τρόπος είναι να αντιγράφουμε το μήνυμα του σφάλματος από την κονσόλα στην μεγαλύτερη μηχανή αναζήτησης Google
Υπάρχουν 6 βασικοί τύποι δεδομένων που μπορούμε να δημιουργήσουμε στην R:
1. Διανύσματα (Vectors)
2. Μήτρες (Matrices)
3. Συστοιχίες (Arrays)
4. Παράγοντες (Factors)
5. Πίνακες (Dataframes)
6. Λίστες (Lists)
Κάθε ένας εξ αυτών των τύπων έχει διαφορετικά χαρακτηριστικά. Οι 4 πρώτοι τύποι περιλαμβάνουν μόνο ομοιογενή στοιχεία (δηλαδή, μόνο αριθμητικά, ποιοτικά ή λογικά δεδομένα), ενώ οι 2 τελευταίοι μπορούν να περιλαμβάνουν ανομοιογενή δεδομένα.
Εικόνα 1. Τύποι δεδομένων
Εικόνα 2. Ομοιογενείς και ανομοιογενείς τύποι δεδομένων
Υπάρχει επίσης ένας επιπλέον τύπος δεδομένων που αποτελεί παραλλαγή του dataframe και ονομάζεται tibble. Θεωρείται (και είναι) ο πιο εύχρηστος τύπος δεδομένων, καθώς είναι αρκετά πιο ευανάγνωστος, περιεκτικός και τακτοποιημένος8.
Πριν δούμε πώς μπορούμε να δημιουργήσουμε οποιονδήποτε τύπο δεδομένων, θα χρειαστεί να κατανοήσουμε πώς γράφουμε κώδικα στην R:
1. Εάν θέλουμε να χρησιμοποιήσουμε ξανά και ξανά κάποια δεδομένα στην ανάλυση μας, θα χρειαστεί να τα αποθηκεύσουμε σε ένα αντικείμενο στην R και να ονοματοδοτήσουμε το αντικείμενο αυτό. Διαλέγουμε ένα όνομα (E.g., numbers) και για να αποθηκεύσουμε τα δεδομένα μας θα πρέπει δεξιά από το όνομα του αντικειμένου να τοποθετήσουμε ένα βέλος (numbers <-). Στη συνέχεια, δεξιά από το βέλος τοποθετούμε τα δεδομένα που θέλουμε να αποθηκεύσουμε σε αυτό το αντικείμενο (numbers <- 1).
2. Θα πρέπει πάντα να έχουμε στο μυαλό μας ότι κατά πάσα πιθανότητα δεν θα θυμόμαστε τι κάνει μια σειρά από εντολές ή γιατί έχουμε γράψει τις συγκεκριμένες εντολές. Κατά συνέπεια, καλό είναι να σχολιάζουμε τον κώδικα μας. Αυτό γίνεται με το σύμβολο #. Οτιδήποτε έπεται του συμβόλου αυτού, θεωρείται ως σχόλιο από την R και δεν το αξιολογεί ως κάτι το οποίο πρέπει να αναλυθεί. Ως εκ τούτου, εάν πληκτρολογήσουμε # numbers <- 1, δεν θα δημιουργηθεί το αντικείμενο numbers.
3. Προκειμένου να είναι ευανάγνωστος ο κώδικας μας, καλό είναι να μην είναι της αρχαιοελληνικής μορφής (Εικόνα 3), αλλά να υπάρχουν κενά διαστήματα μεταξύ των λέξεων/αριθμών/εκφράσεων.
4. Πολύ σημαντικό είναι να ονοματοδοτούμε τα αντικείμενα με τέτοιον τρόπο, ώστε να είναι εύκολο να αντιληφθούμε τι περιέχουν/κάνουν.
## Good names
weather_analysis
emerson_text_analysis
## Bad ones
basic_stuff
detailΚαλό είναι λοιπόν να ακολουθούμε τους ανωτέρω κανόνες9.
Εικόνα 3. Αρχαιοελληνική επιγραφή
Ας δούμε τώρα πώς μπορούμε να γράψουμε κώδικα και να δημιουργήσουμε δεδομένα.
Ένα τυπικό αρχείο που περιέχει κώδικα, έχει την ακόλουθη μορφή:
##===============================================================================##
##
## Thinning and cleaning the occurrence data
##
##===============================================================================##
##=================================================================================
## Load the packages
##=================================================================================
library(spThin)
library(biogeo)
##=================================================================================
##=================================================================================
## Thinning and cleaning
##=================================================================================
## Create petromarula.clim
coordinates(bol_creutz_creutz) <- c("decimalLongitude","decimalLatitude")
pts.clim <- raster::extract(predictors_Crete_current, bol_creutz_creutz, method = "bilinear")
petromarula.clim <- data.frame(cbind(coordinates(bol_creutz_creutz),
pts.clim,
bol_creutz_creutz@data))
## Original number of occurrences
nrow(petromarula.clim)
## Visualization
levelplot(predictors_Crete_current$GRC_msk_alt,
col.regions = colorRampPalette(c('grey90', 'yellow4', 'green4'))(100)) +
layer(sp.points(SpatialPoints(bol_creutz_creutz), pch=20, col=1))
##=================================================================================
##=================================================================================
# It searches for mismatches between country names in the dataset and those
# extracted using the point records. Records for which there are no
# environmental data (based on the object rst) are indicated with a value of one
# in the field called wrongEnv. Low precision records are indicated by a value
# of one in the field lowprec. Environmental outliers are indicated by a value
# of one in a field beginning with the name of the environmental variable and
# ending either in "_e" for records assessed using boxplot statistics (e.g.
# bio1_e) or ending in "_j" for records assessed using the reverse jackknife
# procedure. The recorded elevation values for records (specified with a field
# name in elevc) are compared to digital elevation model values (which are
# returned in the field demElevation) and indicated as a mismatch if they exceed
# the value specified in the parameter called diff (the difference in metres).
##=================================================================================
data(world)
spoccs <- petromarula.clim %>% as.data.frame() %>%
dplyr::rename(x = decimalLongitude, y = decimalLatitude, Species = Taxon) %>%
addmainfields(species = "Species") %>% errorcheck(world, dem = predictors_Crete_current$GRC_msk_alt,
dat = .,
# countries = "country",
vars = c('bio_1', 'bio_2',
'bio_3', 'bio_4',
'bio_5', 'bio_6',
'bio_7', 'bio_8',
'bio_9', 'bio_10',
'bio_11', 'bio_12',
'bio_13', 'bio_14',
'bio_15', 'bio_16',
'bio_17', 'bio_18',
'bio_19', 'GRC_msk_alt'),
res = 0.5,
elevc = "GRC_msk_alt",
diff = 250)
##=================================================================================
##=================================================================================
# The field called "error" will contain a value of one if there are any values of
# one in CountryMismatch, CountryMismatch, wrongEnv or any of the outlier
# fields. The field called "spperr" will contain ones for all records of a
# species for which there are one or more errors.
##=================================================================================
spoccs
spoccs$dups
spoccs$Exclude
spoccs$Reason
spoccs$CountryMismatch
spoccs$wrongEnv
spoccs$lowprec
spoccs$elevMismatch
spoccs$demElevation
spoccs$error
spoccs$spperr
##=================================================================================
##=================================================================================
## Create a new object without duplicate records and records without elevation
##=================================================================================
spoccs_cleared <- spoccs %>% filter(dups != 1 & demElevation != 'NA')
##=================================================================================
##=================================================================================
## Number of occurrences after error checking
##=================================================================================
nrow(spoccs_cleared)
nrow(petromarula.clim)
##=================================================================================
##=================================================================================
## Save results excel
##=================================================================================
library(xlsx)
write.xlsx(spoccs, "./biogeo/Initial results Bolanthus creutzburgii subsp. creutzburgii.xlsx")
write.xlsx(spoccs_cleared, "./biogeo/Final resultsBolanthus creutzburgii subsp. creutzburgii.xlsx")
##=================================================================================
##=================================================================================
## Min distance 1 km, repeat it for 1000 times
##=================================================================================
thinned <- thin(loc.data = spoccs_cleared, lat.col = "y", long.col = "x",
spec.col = "Species", thin.par = 1, reps = 1000, verbose = T,
out.dir = "./Thinned", locs.thinned.list.return = TRUE,
write.files = TRUE, out.base = "Bolanthus creutzburgii subsp. creutzburgii")
##=================================================================================Ας δημιουργήσουμε 3 απλά διανύσματα:
x <- 1
y <- 3
z <- 8Ας δούμε το αποτέλεσμα του πολλαπλασιαμού των διανυσμάτων αυτών:
x * Y * zΓιατί μας βγάζει σφάλμα;
Με το γράμμα c λέμε στην R να ενώσει ότι ακολουθεί
##------------------------
## Numeric data
##------------------------
numbers <- c(0, 1, 1, 2, 3, 5, 8)
numbers
##------------------------
## Text data
##------------------------
words <- c("one", "two", "three")
words
##------------------------
## Logical data
##------------------------
boolean <- c(TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE)
booleanΌσον αφορά δεδομένα κειμένου, πρέπει να βρίσκονται εντός αγγλικών εισαγωγικών. Ας δούμε το ακόλουθο παράδειγμα:
##------------------------
## A famous quote
##------------------------
star.wars <- c("there", "is", "no", "try", ":", "do", "or", "do", "not")
star.wars
##------------------------
## Yet another one
##------------------------
han.solo <- c("I", "have", "a", "bad", "feeling", "about", "this")
han.soloΜπορούμε να ενώσουμε δύο τέτοια διανύσματα ως εξής:
leia.organa <- c(han.solo, "Han", "you", "always", "say", "this")
leia.organaΥπάρχουν αρκετοί τρόποι για να το πετύχουμε αυτό:
##-------------------------------------------------------------------
## Non random numeric data
##-------------------------------------------------------------------
## E.g., from 1 to 10
numbers_non_random <- 1:10
numbers_non_random
## E.g., from 1 to 21 by 2
numbers_non_random <- seq(from = 1, to = 21, by = 2)
numbers_non_random
## E.g., from 1 to 21 adding 1.5
numbers_non_random <- seq(0, 21, length.out = 15)
numbers_non_random
## E.g., from 1 to 21 for two times
numbers_non_random <- rep(1:21, times = 2)
numbers_non_random
## E.g., from 1 to 21 for two times (ordered)
numbers_non_random <- rep(1:21, each = 2)
numbers_non_random
##-------------------------------------------------------------------
## Random numeric data
##-------------------------------------------------------------------
## E.g., Create 25 numbers from 0 to 10 with a normal distribution
random_numbers <- runif(25, min = 0, max = 10)
random_numbers
## E.g., Create 25 numbers from 0 to 10 and replacing them
random_numbers <- sample(0:25, replace = TRUE)
random_numbersΔημιουργήστε τα ακόλουθα διανύσματα:
1. Ένα αριθμητικό διάνυσμα που να περιέχει τους πρώτους 5 ζυγούς αριθμούς
2. Ένα διάνυσμα με δεδομένα κειμένου που να περιέχει τις πρωτεύουσες της Ελλάδας, της Ιταλίας και της Ισπανίας
3. Ένα διάνυσμα που να περιέχει τους αριθμούς από το 32 έως το 79, ανά 3
4. Ένα διάνυσμα που να περιέχει τους ίδιους αριθμούς όπως το προηγούμενο, προσαυξημένους κατά 2.8
5. Ένα διάνυσμα που να περιέχει 49 τυχαίους αριθμούς με ομοιόμορφη κατανομή
##-------------------------
## The solution
##-------------------------
num_vector <- c(2, 4, 6, 8, 10)
capitals <- c("Athens", "Rome", "Madrid")
sec_vector <- seq(from = 31, to = 79, by = 3)
third_vector <- seq(31, 79, length.out = 28)
fourth_vector <- runif(49)Για κάθε μη ομοιόμορφη κατανομή, υπάρχουν 4 τρόποι (λειτουργίες) να δημιουργήσουμε τυχαίους αριθμούς:
1. r random number generation
2. d probability mass function
3. p cumulative distribution
4. q quantiles
##-------------------------------------------------------------------
## Random data creation
##-------------------------------------------------------------------
## In order to replicate the result, we must do the following:
set.seed(1234)
## Normal distribution, zero mean and sd = 1
normal <- rnorm(25, mean = 0, sd = 1)
normal
## Poisson distribution lambda 4
pois <- rpois(25, lambda = 4)
poisΚάντε το ίδιο, δημιουργώντας ένα διάνυσμα για 56 αριθμούς με μέση τιμή 100 και τ.α. 15 το οποίο θα ονομάσετε trial).
Μπορούμε να διαπιστώσουμε εάν όντως το αντικείμενο που δημιουργήσαμε (εν προκειμένω το trial) έχει τις επιθυμητές ιδιότητες με την εντολή summary(trial).
##-------------------------
## The solution
##-------------------------
trial <- rnorm(56, 100, 15)
summary(trial)Αυτό μπορούμε να το κάνουμε με τον εξής τρόπο:
##-------------------------------------------------------------------
## First, we will install the 'stringi' library
##-------------------------------------------------------------------
install.packages("stringi")
##-------------------------------------------------------------------
##-------------------------------------------------------------------
## Then we will load it
##-------------------------------------------------------------------
library(stringi)
##-------------------------------------------------------------------
##-------------------------------------------------------------------
## Then, we will create a variable with 5 elements Each element will be 10
## characters long
##-------------------------------------------------------------------
random_characters <- stri_rand_strings(5, 10)
##-------------------------------------------------------------------
##-------------------------------------------------------------------
## Then, we will create a variable with 5 elements Each element will be 1-10
## characters long
##-------------------------------------------------------------------
random_characters_new <- stri_rand_strings(5, sample(1:10, 5, replace = TRUE))
##-------------------------------------------------------------------Δημιουργήστε ένα αντικείμενο το οποίο να αποτελείται από 12 στοιχεία μήκους 20 χαρακτήρων το καθένα. Στη συνέχεια, δημιουργήστε ένα άλλο αντικείμενο με τον ίδιο αριθμό στοιχείων, διαφορετικού μήκους όμως το καθένα.
##-------------------------
## The solution
##-------------------------
rnd_chr <- stri_rand_strings(12, 20)
another_rnd_chr <- stri_rand_strings(12, sample(1:20, 12, replace = T))Έστω ότι θέλουμε να δημιουργήσουμε ένα νέο διάνυσμα το οποίο περιέχει μόνο τις 3 τελευταίες τιμές του διανύσματος normal. Αυτό γίνεται ως εξής:
normal_subset <- normal[23:25]
normal_subsetΔοκιμάστε το για τις τιμές στις θέσεις 22, 43, 52 του διανύσματος που δημιουργήσατε προηγουμένως (trial).
##-------------------------
## The solution
##-------------------------
trial_subset <- trial[c(22, 43, 52)]Έστω τώρα ότι θέλουμε να δημιουργήσουμε ένα νέο διάνυσμα το οποίο δεν περιέχει μόνο τις 3 τελευταίες τιμές του διανύσματος normal. Αυτό γίνεται ως εξής:
normal_subset <- normal[-c(23:25)]
normal_subsetΔοκιμάστε το για τις τιμές στις θέσεις 16, 28, 39 του διανύσματος που δημιουργήσατε προηγουμένως (trial).
##-------------------------
## The solution
##-------------------------
trial_subset <- trial[-c(16, 28, 39)]Εάν θέλουμε να διαλέξουμε συγκεκριμένες τιμές ενός διανύσματος, ενεργούμε ως εξής:
##-------------------------------------------------------------------
## Create some random numbers
##-------------------------------------------------------------------
set.seed(1234)
random_numbers <- runif(250, min = 0, max = 1245)
random_numbers
new_numbers <- random_numbers[random_numbers > 851]Δοκιμάστε το για τιμές μικρότερες από 5.
##-------------------------
## The solution
##-------------------------
new_numbers <- random_numbers[random_numbers < 5]Εάν θέλουμε να αλλάξουμε συγκεκριμένες τιμές ενός διανύσματος, ενεργούμε ως εξής:
## Create some random numbers
set.seed(1234)
random_numbers <- runif(40, min = 0, max = 394)
random_numbers## [1] 44.8 245.2 240.1 245.6 339.2 252.3 3.7 91.6 262.4 202.6 273.3
## [12] 214.7 111.4 363.8 115.2 329.9 112.8 105.1 73.6 91.5 124.7 119.3
## [23] 62.7 15.8 86.2 319.4 207.1 360.4 327.5 18.0 179.7 104.5 120.0
## [34] 199.9 71.4 299.3 79.3 102.0 390.9 318.1
random_numbers[random_numbers < 49] <- 0Μετατρέψτε τις τιμές που είναι μεγαλύτερες από 100 σε 200.
##-------------------------
## The solution
##-------------------------
random_numbers[random_numbers > 100] <- 2001. Επιλέξτε την πρώτη εγγραφή του αντικειμένου star.wars.
2. Δοκιμάστε το για την 3η, την 5η και την 7η
3. Επιλέξτε την 1η έως την 4η εγγραφή
4. Δοκιμάστε το για την 5η έως και την 9η
5. Επιλέξτε τις εγγραφές 8, 9 και 4 (με αυτή τη σειρά)
6. Επιλέξτε όλες τις εγγραφές, εκτός της 2ης
7. Επιλέξτε όλες τις εγγραφές, εκτός της 3ης και της 5ης
##-------------------------
## The solution
##-------------------------
star.wars[1]
star.wars[c(3, 5, 7)]
star.wars[1:4]
star.wars[5:9]
star.wars[c(8, 9, 4)]
star.wars[-2]
star.wars[-c(3, 5)]Όλα τα δεδομένα μετατρέπονται σε δεδομένα κειμένου10.
numeric_data <- 2:8
mix <- c(numeric_data, star.wars)
mix1. length() αφορά τον αριθμό των στοιχείων που περιέχει το διάνυσμα
2. sort() ταξινομεί τα στοιχεία του διανύσματος κατά αύξοντα αριθμό
3. duplicated() ποιά στοιχεία είναι διπλοεγγραφές
4. unique() ποιά στοιχεία δεν είναι διπλοεγγραφές
Δοκιμάστε το με το ακόλουθο διάνυσμα: random_numbers <- runif(8, min = 5, max = 12)
Μπορούμε επίσης να συγκρίνουμε δύο διανύσματα που περιέχουν αριθμητικά δεδομένα:
1. x < y is x less than y
2. x > y is x greater than y
3. x <= y is x less than or equal to y
4. x >= y is x greater than or equal to y
5. x == y is x equal to y
6. x != y is x not equal to y
x <- 9
y <- 10
x == y
x < y
x != yΔοκιμάστε το και για τα ακόλουθα διανύσματα: x <- c (1, 4, 9, 12) και y <- c (4, 4, 9, 13). Ποιό είναι το αποτέλεσμα του x == y;
Πόσα ζεύγη τιμών στα δύο αυτά διανύσματα είναι ίδια;
sum(x == y)Σε ποιές θέσεις βρίσκονται αυτά τα ζεύγη;
which(x == y)Με την εντολή matrix(), η οποία περιέχει τα ακόλουθα επιχειρήματα (arguments):
vector περιέχει τα στοιχεία της μήτραςnrow & ncol πόσες σειρές και στήλες, αντίστοιχα θα έχει η μήτραdimnames όνομα του κάθε διανύσματοςbyrow εάν η μήτρα θα γεμίσει με δεδομένα πρώτα σε κάθε σειρά (byrow = TRUE) ή στήλη (byrow = FALSE)##-------------------------
## An example
##-------------------------
my_first_matrix <- matrix(1:20, nrow = 5, ncol = 4)
my_first_matrixΔοκιμάστε το με το byrow = T.
##-------------------------
## Another example
##-------------------------
cells <- c(1, 26, 24, 68) ## Cells
rnames <- c("R1", "R2") ## Row names
cnames <- c("C1", "C2") ## Column names
mymatrix <- matrix(cells, nrow = 2, ncol = 2, byrow = TRUE, dimnames = list(rnames,
cnames)) ## Create a 2 x 2 matrix
mymatrixΔημιουργήστε ένα αντικείμενο ονόματι cells το οποίο να περιέχει 24 τιμές με κανονική κατανομή, μέση τιμή ίση με 100 και τυπική απόκλιση ίση με 22. Στη συνέχεια, δημιουργήστε μια μήτρα αποτελούμενη από 12 σειρές και δύο στήλες, γεμίζοντας τις σειρές πρώτα. Μην συμπληρώσετε το dimnames. Ποιό είναι το αποτέλεσμα;
##-------------------------
## The solution
##-------------------------
cells <- rnorm(24, mean = 100, sd = 22)
mymatrix <- matrix(cells, nrow = 12, ncol = 2, byrow = TRUE)
mymatrixΤι παρατηρείτε σχετικά με το όνομα των σειρών και των στηλών11;
Έστω ότι οι 12 αυτές σειρές αντιπροσωπεύουν δώδεκα διαφορετικά σημεία δειγματοληψίας, τα οποία θέλουμε να τα ονομάσουμε Site_1 έως Site_12. Με την εντολή row.names(mymatrix) <- paste0("Site_", 1:12) μπορούμε να το κάνουμε αυτό πολύ γρήγορα. Η εντολή paste0 ενώνει το "Site_" με την αλληλουχία αριθμών από το 1 έως το 12. Με την εντολή colnames(mymatrix) <- c('Biomass', 'Carbon_dioxide') ονομάζουμε την πρώτη και την δεύτερη στήλη Biomass και Carbon_dioxide, αντίστοιχα.
1. dim() διαστάσεις της εκάστοτε μήτρας (πρώτα ο αριθμός των σειρών και μετά οι στήλες)
2. rowSums() άθροισμα κατά σειρά
3. colSums() άθροισμα κατά στήλη
4. rowMeans() μέση τιμή κατά σειρά
5. colMeans() μέση τιμή κατά στήλη
Ειδικά για τις μήτρες, προκειμένου να εφαρμόσουμε κάποια πιο σύνθετη πιθανόν εντολή, μπορούμε να χρησιμοποιήσουμε τον ακόλουθο κώδικα, για να δούμε κάποιες π.χ., βασικές στατιστικές ιδιότητες (median, quantile, range) ή για να μετατρέψουμε τις τιμές (log, log10, sqrt, cos, tan, sin):
apply(mymatrix, 2, sd)
apply(mymatrix, 2, median)
apply(mymatrix, 2, quantile)
apply(mymatrix, 2, range)
apply(mymatrix, 2, log)
apply(mymatrix, 2, log10)
apply(mymatrix, 2, sqrt)
apply(mymatrix, 2, cos)
apply(mymatrix, 2, sin)
apply(mymatrix, 2, tan)Ο αριθμός 2 αφορά τις στήλες, ενώ ο αριθμός 1 αφορά τις σειρές.
Δοκιμάστε το και εσείς στη μήτρα mymatrix με τον αριθμό 1, όπως και τις προαναφερθείσες 5 εντολές.
##-------------------------
## The solution
##-------------------------
dim(mymatrix)
rowSums(mymatrix)
colSums(mymatrix)
rowMeans(mymatrix)
colMeans(mymatrix)
apply(mymatrix, 1, sd)
apply(mymatrix, 1, median)
apply(mymatrix, 1, quantile)
apply(mymatrix, 1, range)
apply(mymatrix, 1, log)
apply(mymatrix, 1, log10)
apply(mymatrix, 1, sqrt)
apply(mymatrix, 1, cos)
apply(mymatrix, 1, sin)
apply(mymatrix, 1, tan)Έστω ότι θέλουμε να δημιουργήσουμε μια νέα μήτρα η οποία περιέχει την 10η σειρά και την 1η στήλη του αντικειμένου mymatrix ή τις σειρές 7 έως 9 και από τις 2 στήλες. Αυτό γίνεται ως εξής:
mymatrix_new <- mymatrix[10, 1]
mymatrix_new
mymatrix_new <- mymatrix[7:9, ]
mymatrix_newΔημιουργήστε πρώτα ένα νέο διάνυσμα ονόματι trial το οποίο θα αποτελείται από 200 στοιχεία, με μέση τιμή 1209 και τυπική απόκλιση 249, με κανονική κατανομή. Στη συνέχεια, δημιουργήστε μια νέα μήτρα ονόματι my_second_matrix η οποία θα έχει 25 σειρές και 8 στήλες. Δεν θα γεμίσετε τις σειρές πρώτα. Η μήτρα αυτή θα βασίζεται στο διάνυσμα trial το οποίο θα είναι ταξινομημένο κατά αύξοντα αριθμό12. Ονομάστε τις σειρές έχοντας ως πρόθεμα το Site_ και τις στήλες έχοντας ως πρόθεμα το Species_ βάσει των όσων μάθατε προηγουμένως13. Ποιά είναι η μέση τιμή, η τυπική απόκλιση και το εύρος για το κάθε είδος και την κάθε περιοχή δειγματοληψίας;
##-------------------------
## The solution
##-------------------------
trial <- rnorm(200, mean = 1209, sd = 249)
my_second_matrix <- matrix(sort(trial), nrow = 25, ncol = 8, byrow = F)
my_second_matrix
row.names(my_second_matrix) <- paste0("Site_", 1:25)
colnames(mymatrix) <- paste0("Species_", 1:8)Δημιουργήστε μια νέα μήτρα ονόματι my_third_matrix η οποία θα περιέχει τα είδη 2 έως 5 και όλες τις θέσεις δειγματοληψίας. Ποιές είναι οι διαστάσεις της μήτρας αυτής14; Μετατρέψτε τις τιμές του my_third_matrix βάσει του νεπέριου λογάριθμου15. Ποιο είναι το εύρος των τιμών για κάθε είδος και κάθε θέση δειγματοληψίας16; Δημιουργήστε στη συνέχεια ένα νέο αντικείμενο ονόματι my_fourth_matrix το οποίο θα περιέχει όλα τα είδη του my_third_matrix, αλλά μόνο τις θέσεις δειγματοληψίας 4 έως 8 και 17 έως 2117.
##-------------------------
## The solution
##-------------------------
my_third_matrix <- my_second_matrix[, 2:5]
dim(my_third_matrix)
my_third_matrix <- apply(my_third_matrix, 2, log)
apply(my_third_matrix, 2, range)
apply(my_third_matrix, 1, range)
my_fourth_matrix <- my_third_matrix[c(4:8, 17:21), ]Με την εντολή data.frame():
##-------------------------
## An example
##-------------------------
patientID <- c(1, 2, 3, 4) ## Numeric vector
age <- c(25, 34, 28, 52) ## Numeric vector
diabetes <- c("Type1", "Type2", "Type1", "Type1") ## Character vector
status <- c("Poor", "Improved", "Excellent", "Poor") ## Character vector
patientdata <- data.frame(patientID, age, diabetes, status)
patientdata1. dim() διαστάσεις του εκάστοτε πίνακα
2. summary() βασικές στατιστικές ιδιότητες για κάθε μεταβλητή
3. str() πληροφορίες για κάθε στήλη
4. Με το σύμβολο $ μπορούμε να επιλέξουμε μια στήλη από τον πίνακα
5. head() πρώτες έξι σειρές
6. tail() τελευταίες έξι σειρές
7. cbind() ενώνει δύο αντικείμενα κατά στήλες
8. row.names() τα ονόματα των σειρών
9. colnames() τα ονόματα των στηλών
##-------------------------
## A cbind example
##-------------------------
age_2 <- c(29, 38, 16, 44)
new_patient_data <- cbind(patientdata, age_2)
new_patient_dataΕΦαρμόστε τις ανωτέρω εντολές στον πίνακα patientdata που δημιουργήσαμε προηγουμένως. Στη συνέχεια με την εντολή data(mtcars), φορτώστε αυτό το σετ δεδομένων και τρέξτε ξανά τις προαναφερθείσες εντολές για αυτόν τον πίνακα. Ποιές οι διαστάσεις και οι βασικές στατιστικές ιδιότητες του αντικειμένου mtcars; Επιλέξτε τη μεταβλητή disp και δημιουργήστε ένα νέο αντικείμενο, ονόματι disp_log το οποίο θα είναι η λογαριθμημένη εκδοχή (λογάριθμος του 10) της μεταβλητής disp. Στη συνέχεια με την βοήθεια της εντολή row.names(), δημιουργήστε ένα νέο αντικείμενο ονόματι Cars. Ενώστε τα αντικείμενα mtcars, Cars και disp_log.
##-------------------------
## The solution
##-------------------------
dim(patientdata)
summary(patientdata)
str(patientdata)
head(patientdata)
tail(patientdata)
data(mtcars)
dim(mtcars)
summary(mtcars)
disp_log <- log10(mtcars$disp)
Cars <- row.names(mtcars)
new_df <- cbind(mtcars, Cars, disp_log)Δημιουργήστε ένα dataframe με 2 στήλες (μεταβλητές), όπου:
1. Η πρώτη να περιέχει 25 τυχαίους αριθμούς από το 1 έως το 100
2. Η δεύτερη να περιέχει 25 τυχαίους αριθμούς με κατανομή Poisson και lambda 7
και ονομάστε το my_first_dataframe.
##-------------------------
## The solution
##-------------------------
first_var <- runif(25, 1, 100)
sec_var <- rpois(25, lambda = 7)
my_first_dataframe <- cbind(first_var, sec_var)Έχουμε δει ότι με το σύμβολο $ μπορούμε να διαλέξουμε μια στήλη/μεταβλητή από έναν πίνακα. Εάν θέλουμε να επιλέξουμε όμως περισσότερες από μια στήλες/μεταβλητές και ένα υποσύνολο των σειρών/παρατηρήσεων, ενεργούμε ως εξής:
##-------------------------------------------------------------------
## First load the data-set
##-------------------------------------------------------------------
data(mtcars)
##-------------------------------------------------------------------
##-------------------------------------------------------------------
## Then check the first 6 rows
##-------------------------------------------------------------------
head(mtcars)
##-------------------------------------------------------------------
##-------------------------------------------------------------------
## Subset the data-set, selecting the columns 2 to 4
##-------------------------------------------------------------------
mtcars_subset <- mtcars[, 2:4]
##-------------------------------------------------------------------
##-------------------------------------------------------------------
## Do it by specifying their names
##-------------------------------------------------------------------
mtcars_subset_another_way <- mtcars[, c("cyl", "disp", "hp")]
##-------------------------------------------------------------------
##-------------------------------------------------------------------
## Are the two objects the same?
##-------------------------------------------------------------------
identical(mtcars_subset, mtcars_subset_another_way)
##-------------------------------------------------------------------
##-------------------------------------------------------------------
## Subset the data-set by selecting rows 4-6 and 8-10 and the first 3 columns
##-------------------------------------------------------------------
mtcars_subset <- mtcars[c(4:6, 8:10), 1:3]
##-------------------------------------------------------------------Αυτός ο τύπος αντικείμενου είναι μια ποιοτική μεταβλητή, η οποία μπορεί να είναι ταξινομημένη κατά μέγεθος.
##------------------------------------------------------------------------------
## An example
##------------------------------------------------------------------------------
## Let's first create two numeric vectors
patientID <- c(1, 2, 3, 4)
age <- c(25, 34, 28, 52)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Then two qualitative vectors
##------------------------------------------------------------------------------
diabetes <- c("Type1", "Type2", "Type1", "Type1")
status <- c("Poor", "Improved", "Excellent", "Poor")
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Join them in a dataframe
##------------------------------------------------------------------------------
patientdata <- data.frame(patientID, age, diabetes, status)
##------------------------------------------------------------------------------Με την εντολή class(diabetes) μπορούμε να διαπιστώσουμε τι είδους μεταβλητή είναι αυτή. Ποιο είναι το αποτέλεσμα της εντολής summary(diabetes);
Ας πάρουμε την πρώτη ποιοτική μεταβλητή (diabetes). Για να την μετατρέψουμε σε factor, κάνουμε το εξής:
diabetes <- factor(diabetes)
diabetesΤι είδους μεταβλητή είναι τώρα ο diabetes; Ποιο είναι τώρα το αποτέλεσμα της εντολής summary(diabetes);
Εάν τώρα έχουμε μια ποιοτική μεταβλητή, η οποία είναι ιεραρχικα διαβαθμισμένη, θα προσθέσουμε ordered = TRUE. Μια τέτοια μεταβλητή είναι το status
status <- factor(status, ordered = TRUE)
statusΓιατί;
Γιατί ο φτωχός (poor) ασθενής έχει μικρότερη οικονομική άνεση από ότι ο εύπορος (excellent) ασθενής και θα πάρει κατώτερη τιμή (3 αντί για 1 - θυμηθείτε μιλάμε για ιεράρχιση, οπότε το 1 είναι πιο πάνω από το 3).
Όμως, by default η R κατασκευάζει τα επίπεδα των factor μεταβλητών με αλφαβητική σειρά.
Με τη μεταβλητή status δεν είχαμε πρόβλημα, γιατί όντως η οικονομική κατάσταση των ασθενών ακολουθούσε αυτή τη σειρά (Excellent, Improved, Poor). Εάν όμως αντί για Poor ήταν Ailing (και αυτό σημαίνει φτωχός), θα υπήρχε πρόβλημα.
Τί κάνουμε σε αυτή την περίπτωση;
Μπορούμε να υπερκεράσουμε την default επιλογή, χρησιμοποιώντας την έκφραση levels
Επί παραδείγματι:
status <- factor(status, order = TRUE, levels = c("Poor", "Improved", "Excellent"))Με αυτόν τον τρόπο, 1 = Poor, 2 = Improved, 3 = Excellent (Το 3 εδώ είναι το καλύτερο).
ΠΡΟΣΟΧΗ Πρέπει να δώσουμε τιμές για όλα τα επίπεδα της ποσοτικής μας μεταβλητής. Εάν δεν γίνει αυτό, αυτές που δεν θα έχουν καθοριστεί με την έκφραση levels, δεν θα ληφθούν υπ’όψιν.
Με την εντολή gl που έχει 3 arguments (up to, with repeats of, to total length). Ας δούμε ένα απλό παράδειγμα:
##------------------------------------------------------------------------------
## Generate four levels, each repeated 3 times (total length thus is 12)
##------------------------------------------------------------------------------
gl(4, 3)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## The same but repeated twice
##------------------------------------------------------------------------------
gl(4, 3, 24)
##------------------------------------------------------------------------------Κάντε το ίδιο αλλά επαναλαμβάνοντας το μοτίβο 3 και 6 φορές.
##-------------------------
## The solution
##-------------------------
gl(4, 3, 36)
gl(4, 3, 72)Εάν επιθυμούμε το ποιοτικό αντικείμενο που θα δημιουργήσουμε να περιέχει κείμενο και όχι αριθμούς, δρούμε ως εξής:
##------------------------------------------------------------------------------
## Create an object with two levels, each repeated 2 times for a total length
## of 24
##------------------------------------------------------------------------------
Temp <- gl(2, 2, 24, labels = c("Low", "High"))
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Create an object with three levels, each repeated 8 times for a total
## length of 24
##------------------------------------------------------------------------------
Soft <- gl(3, 8, 24, labels = c("Hard", "Medium", "Soft"))
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Create an object with two levels, each repeated 4 times for a total length
## of 24
##------------------------------------------------------------------------------
M.user <- gl(2, 4, 24, labels = c("N", "Y"))
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Create an object with two levels, each repeated once for a total length of
## 24
##------------------------------------------------------------------------------
Brand <- gl(2, 1, 24, labels = c("X", "M"))
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Bind them all together in a dataframe
##------------------------------------------------------------------------------
all_together <- data.frame(Temp, Soft, M.user, Brand)
##------------------------------------------------------------------------------ Δημιουργήστε μια ποιοτική μεταβλητή ονόματι:
1. Rainfall με 4 επίπεδα επαναλαμβανόμενα 3 φορές. Τα επίπεδα να είναι none, little, medium και large. 2. Climate με 6 επίπεδα επαναλαμβανόμενα 2 φορές. Τα επίπεδα να είναι dry, humid, subhumid, tropical, subtropical και arctic.
##-------------------------
## The solution
##-------------------------
Rainfall <- gl(4, 3, labels = c("none", "little", "medium", "large"))
Climate <- gl(6, 2, labels = c("dry", "humid", "subhumid", "tropical", "subtropical",
"arctic"))1. levels() διαστάσεις του εκάστοτε πίνακα
2. nlevels() βασικές στατιστικές ιδιότητες για κάθε μεταβλητή
3. str() πληροφορίες για κάθε στήλη
4. class()
Εγκαταστήστε και φορτώστε τις βιβλιοθήκες forcats και gapminder.
Εφαρμόστε τις ανωτέρω εντολές στις κατάλληλες μεταβλητές από το σετ δεδομένων gapminder (data(gapminder)).
Ποιές είναι αυτές και πόσα επίπεδα έχουν;
##-------------------------
## The solution
##-------------------------
## Install the libraries
install.packages("forcats")
install.packages("gapminder")
## Load the libraries
library(forcats)
library(gapminder)
## Load the data
data(gapminder)
## See the data
gapminder
## Use the functions
str(gapminder)
levels(gapminder$country)
levels(gapminder$continent)
nlevels(gapminder$country)
nlevels(gapminder$continent)Μέσω της βιβλιοθήκης forcats, μπορούμε να το διαπιστώσουμε αυτό ως εξής:
fct_count(gapminder$continent)Ως εξής:
##------------------------------------------------------------------------------
## First check how many countries are there (142)
##------------------------------------------------------------------------------
nlevels(gapminder$country)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Then select some of those countries
##------------------------------------------------------------------------------
h_countries <- c("Egypt", "Haiti", "Romania", "Thailand", "Venezuela")
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## And subset the original data
##------------------------------------------------------------------------------
## The %in% symbol finds and keeps only those values of country fulfil the
## condition described in h_countries
h_gap <- subset(gapminder, country %in% h_countries)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Use either the base function
##------------------------------------------------------------------------------
h_gap <- droplevels(h_gap)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## or the function from forcats
##------------------------------------------------------------------------------
h_gap$country <- fct_drop(h_gap$country)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Then check if the number of levels dropped
##------------------------------------------------------------------------------
nlevels(h_gap$country)
##------------------------------------------------------------------------------ Κάντε το ίδιο (με όποιον από τους δύο τρόπους επιθυμείτε) για τις χώρες Rwanda, Greece, Uruguay, Comoros, Croatia, Argentina και Mali.
##-------------------------
## The solution
##-------------------------
h_countries <- c("Rwanda", "Greece", "Uruguay", "Comoros", "Croatia", "Argentina",
"Mali")
h_gap <- subset(gapminder, country %in% h_countries)
h_gap$country <- fct_drop(h_gap$country)
nlevels(h_gap$country)Στην R τα επίπεδα μιας πlοιοτικής μεταβλητής είναι με αλφαβητική σειρά εξ ορισμού. Μπορούμε όμως να άλλαξουμε αυτή τη σειρά βάσει κάποιας αρχής, όπως επί παραδείγματι:
1. Συχνότητα του εκάστοτε επιπέδου (π.χ., το πιο συχνό να εμφανίζεται πρώτο)
2. Κάποια άλλη - ποσοτική - μεταβλητή 3. Με τη σειρά που εμείς επιθυμούμε
Ας δούμε ένα παράδειγμα:
##------------------------------------------------------------------------------
## Default order is alphabetical
##------------------------------------------------------------------------------
levels(gapminder$continent)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Order by frequency
##------------------------------------------------------------------------------
freq_gap <- fct_infreq(gapminder$continent)
levels(freq_gap)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Backwards!
##------------------------------------------------------------------------------
freq_gap_bw <- fct_infreq(gapminder$continent)
freq_gap_bw <- fct_rev(freq_gap_bw)
levels(freq_gap_bw)
##------------------------------------------------------------------------------ Εγκαταστήστε και φορτώστε την βιβλιοθήκη ggplot2. Με την εντολή data(diamonds), φορτώστε το εν λόγω σετ δεδομένων. Μετατρέψτε τη στήλη cut σε ποιοτική (factor) μεταβλητή. Πόσα επίπεδα έχει; Στη συνέχεια, αλλάξτε τη σειρά των επιπέδων της βάσει της συχνότητας εμφάνισης.
##-------------------------
## The solution
##-------------------------
data(diamonds)
diamonds$cut <- factor(diamonds$cut)
freq_gap <- fct_infreq(diamonds$cut)
levels(freq_gap)Ας δούμε πώς μπορούμε να αλλάξουμε τη σειρά των επιπέδων μιας ποιοτικής μεταβλητής βάσει μιας ποσοτικής μεταβλητής:
##------------------------------------------------------------------------------
## Order countries by median life expectancy
##------------------------------------------------------------------------------
head(levels(fct_reorder(gapminder$country, gapminder$lifeExp) ## The default is the median
))
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Order accoring to minimum life exp instead of median
##------------------------------------------------------------------------------
head(levels(fct_reorder(gapminder$country, gapminder$lifeExp, min) ## You can try sd or max if you want
))
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Backwards!
##------------------------------------------------------------------------------
head(levels(fct_reorder(gapminder$country, gapminder$lifeExp, .desc = TRUE) ## In descending order
))
##------------------------------------------------------------------------------ Φορτώστε την βιβλιοθήκη ggplot2. Με την εντολή data(diamonds), φορτώστε το εν λόγω σετ δεδομένων. Μετατρέψτε τη στήλη cut σε ποιοτική (factor) μεταβλητή. Στη συνέχεια, αλλάξτε τη σειρά των επιπέδων της βάσει της μεταβλητής price σύμφωνα με το παράδειγμα.
##-------------------------
## The solution
##-------------------------
data(diamonds)
diamonds$cut <- factor(diamonds$cut)
head(levels(fct_reorder(diamonds$cut, diamonds$price)))
head(levels(fct_reorder(diamonds$cut, diamonds$price, min)))
head(levels(fct_reorder(diamonds$cut, diamonds$price, .desc = TRUE)))Ας δούμε πώς μπορούμε να αλλάξουμε τη σειρά των επιπέδων μιας ποιοτικής μεταβλητής όπως εμείς επιθυμούμε:
##------------------------------------------------------------------------------
## Let's check the levels of the h_gap object we created earlier
##------------------------------------------------------------------------------
levels(h_gap$country)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Then let's change their order with the fct_relevel command
##------------------------------------------------------------------------------
levels(fct_relevel(h_gap$country, "Romania", "Haiti"))
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Or in this way
##------------------------------------------------------------------------------
levels(fct_relevel(h_gap$country, c("Thailand", "Romania"), "Haiti"))
##------------------------------------------------------------------------------ Φορτώστε την βιβλιοθήκη ggplot2. Με την εντολή data(diamonds), φορτώστε το εν λόγω σετ δεδομένων. Μετατρέψτε τη στήλη cut σε ποιοτική (factor) μεταβλητή. Στη συνέχεια, αλλάξτε τη σειρά των επιπέδων της τοποθετώντας τα επίπεδα Good και Ideal πριν το επίπεδο Fair. Τέλος, τοποθετήστε το επίπεδο Premium πριν το επίπεδο Good.
##-------------------------
## The solution
##-------------------------
data(diamonds)
diamonds$cut <- factor(diamonds$cut)
levels(diamonds$cut)
levels(fct_relevel(diamonds$cut, c("Good", "Ideal"), "Fair"))
levels(fct_relevel(diamonds$cut, "Premium", "Good"))Αυτό μπορούμε να το κάνουμε με την εντολή fct_recode. Ας δούμε ένα παράδειγμα:
##------------------------------------------------------------------------------
## Let's first create a factor
##------------------------------------------------------------------------------
x <- factor(c("apple", "bear", "banana", "deer"))
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## And check its' levels
##------------------------------------------------------------------------------
levels(x)
##------------------------------------------------------------------------------
##------------------------------------------------------------------------------
## Then let's change the names of some of its' levels
##------------------------------------------------------------------------------
fct_recode(x, fruit = "apple", fruit = "banana")
##------------------------------------------------------------------------------ Βάσει του ανωτέρω παραδείγματος μετατρέψτε τα επίπεδα bear και deer στο επίπεδο animal.
Φορτώστε την βιβλιοθήκη ggplot2. Με την εντολή data(diamonds), φορτώστε το εν λόγω σετ δεδομένων. Μετατρέψτε τη στήλη cut σε ποιοτική (factor) μεταβλητή. Στη συνέχεια, αλλάξτε τα επιπέδα Fair, Good και Very Good σε Low_quality και τα επίπεδα Premium και Ideal σε Excellent_quality.
##-------------------------
## The solution
##-------------------------
data(diamonds)
diamonds$cut <- factor(diamonds$cut)
levels(diamonds$cut)
fct_recode(diamonds$cut, Low_quality = "Fair", Low_quality = "Good", Low_quality = "Very Good",
Excellent_quality = "Premium", Excellent_quality = "Ideal")Είναι ένας από τους δύο18 πιο σημαντικούς τύπους αντικείμενου στην R. Μπορεί να περιέχει όπως και οι πίνακες ανομοιογενή δεδομένα διαφορετικού όμως μήκους. Αποτελεί στην ουσία μια ιεραρχημένη συλλογή (πιθανόν άσχετων μεταξύ τους) αντικειμένων. Μπορούμε να δημιουργήσουμε μια λίστα με την εντολή list. Ας δούμε κάποια παραδείγματα:
## ==============================================================================
## First example of creating a list
## ==============================================================================
## Create some data
apples <- c(4, 4.5, 4.2, 5.1, 3.9)
oranges <- c(TRUE, TRUE, FALSE)
chalk <- c("limestone", "marl", "oolite", "CaC03")
cheese <- c(3.2 - (0+4.5i), 12.8 + (0+2.2i))
## ==============================================================================
## ==============================================================================
## What would happen if we joined them in a dataframe?
## ==============================================================================
data.frame(apples, oranges, chalk, cheese)
## ==============================================================================
## ==============================================================================
## Bind them in a list
## ==============================================================================
items <- list(apples, oranges, chalk, cheese)
items
## ==============================================================================Δημιουργήστε τα εξής 5 διαφορετικά αντικείμενα:
1. Το random_numbers που περιέχει 20 τυχαίους αριθμούς με μέση τιμή 12 και τ.α. 24.
2. Το random_characters που περιέχει 30 στοιχεία διαφορετικού μήκους όσον αφορά τον αριθμό των χαρακτήρων με μέγιστο αριθμό χαρακτήρων 45 και ελάχιστο 12
3. Μια μήτρα ονόματι random_matrix 10 σειρών και 2 στηλών που θα περιέχει ένα διάνυσμα ονόματι fubar το οποίο θα αποτελείται από 20 στοιχεία, με μέση τιμή 29 και τυπική απόκλιση 2, με κανονική κατανομή.
4. Το geological_substrata που περιέχει τα ακόλουθα γεωλογικά υποστρώματα: dacite, andecite, limestone, sandstone, schist και marble.
5. Έναν παράγοντα (factor) ονόματι stress με 3 επίπεδα (levels - Extreme, Zen, Mild), καθένα εκ των οποίων επαναλαμβάνεται 20 φορές
και στη συνέχεια ενώστε τα στη λίστα my_first_list.
##-------------------------
## The solution
##-------------------------
## First vector
random_numbers <- rnorm(20, mean = 12, sd = 24)
## Second vector
random_characters <- stringi::stri_rand_strings(30, sample(12:45, 30, replace = TRUE))
## Matrix
fubar <- rnorm(20, mean = 29, sd = 2)
random_matrix <- matrix(fubar, nrow = 10, ncol = 2)
## Third vector
geological_substrata <- c("dacite", "andecite", "limestone", "sandstone", "schist",
"marble")
## Factor
stress <- gl(3, 20, labels = c("Extreme", "Zen", "Mild"))
## List creation
my_first_list <- list(random_numbers, random_characters, random_matrix, geological_substrata,
stress)Μπορούμε να δημιουργήσουμε μια λίστα δίνοντας ένα διαφορετικό όνομα σε κάθε στοιχείο της λίστας ώς εξής:
## ==============================================================================
## Second example of creating a list
## ==============================================================================
## Create some data
apples <- c(4, 4.5, 4.2, 5.1, 3.9)
oranges <- c(TRUE, TRUE, FALSE)
chalk <- c("limestone", "marl", "oolite", "CaC03")
cheese <- c(3.2 - (0+4.5i), 12.8 + (0+2.2i))
## ==============================================================================
## ==============================================================================
## Bind them in a list
## ==============================================================================
items <- list(red_fruit = apples, juicy_fruit = oranges, messy_white_thing = chalk,
tasty_white_thing = cheese)
items
## ==============================================================================Φτιάξτε ξανά τη λίστα από την προηγούμενη άσκηση και αυτή τη φορά ονοματοδοτήστε τα 5 αντικείμενα της, ώστε το κάθε αντικείμενο της λίστας να έχει το δικό του όνομα. Τα ονόματα που θα δώσετε είναι τα ακόλουθα: foraminifera_concetration, Species_name, Sites_abundance, Geology, Stress_levels.
##-------------------------
## The solution
##-------------------------
my_first_list <- list(foraminifera_concetration = random_numbers, Species_name = random_characters,
Sites_abundance = random_matrix, Geology = geological_substrata, Stress_levels = stress)Μπορούμε να δημιουργήσουμε μια άδεια λίστα με προκαθορισμένο μήκος (length) με την εντολή vector ώς εξής19:
## ==============================================================================
## Create an empty list
## ==============================================================================
empty_list <- vector("list", length = 5)
empty_list
## ==============================================================================Αυτό μπορεί να γίνει με το σύμβολο [[]] για να επιλέξουμε ένα από τα αντικείμενα της λίστας και με το σύμβολο [] για να επιλέξουμε ένα στοιχείο από ένα αντικείμενο της λίστας. Εάν τα αντικείμενα της λίστας έχουν όνομα, τότε μπορούμε να χρησιμοποιήσουμε το σύμβολο $. Εάν θέλουμε να επιλέξουμε περισσότερα του ενός αντικείμενα από μια λίστα, τότε χρησιμοποιούμε το σύμβολο []. Ας δούμε ένα παράδειγμα:
## ==============================================================================
## Using the previous example of list creation
## ==============================================================================
## Create some data
apples <- c(4, 4.5, 4.2, 5.1, 3.9)
oranges <- c(TRUE, TRUE, FALSE)
chalk <- c("limestone", "marl", "oolite", "CaC03")
cheese <- c(3.2 - (0+4.5i), 12.8 + (0+2.2i))
## ==============================================================================
## ==============================================================================
## Bind them in a list
## ==============================================================================
items <- list(red_fruit = apples, juicy_fruit = oranges, messy_white_thing = chalk,
tasty_white_thing = cheese)
items
## ==============================================================================
## ==============================================================================
## Selection of list objects
## ==============================================================================
## Let's say we want to select the third object of this list
items[[3]]
## Or the second element of the third object
items[[3]][2]
## Does our list have names?
names(items)
## Since our list is named, we can use the `$` symbol to select the third
## object
items$messy_white_thing
## ==============================================================================
## ==============================================================================
## Selection of multiple list objects
## ==============================================================================
## If we want to select two (or more) list objects, then we will use only one
## pair of brackets
items[1:2]
items[c(1, 3)]
## ==============================================================================Επιλέξτε από τη λίστα που δημιουργήσατε προηγούμενως (τη my_first_list δηλαδή), το 5ο αντικείμενο αυτής και με τους δύο τρόπους που αναφέραμε. Στη συνέχεια, επιλέξτε από το 2ο αντικείμενο της λίστας, το 22ο στοιχείο του. Ακολούθως, επιλέξτε το 2ο, το 4ο και το 5ο αντικείμενο της λίστας. Τέλος, επιλέξτε το 3ο και το 4ο.
##-------------------------
## The solution
##-------------------------
my_first_list[[5]]
my_first_list$Stress_levels
my_first_list[[2]][22]
my_first_list[c(2, 4, 5)]
my_first_list[3:4]1. str() πληροφορίες για κάθε αντικείμενο της λίστας
2. length() ο αριθμός των αντικειμένων της λίστας
3. lapply() λειτουργία (function) που εφαρμόζει μια άλλη λειτουργία σε κάθε αντικείμενο μιας λίστας
4. list.append() προσθέτει αντικείμενα σε μια λίστα20
5. names() τα ονόματα των αντικειμένων μιας λίστας
Ας δούμε ένα παράδειγμα για κάθε μια εξ αυτών των εντολών:
## ==============================================================================
## Some basic functions
## ==============================================================================
str(items)
length(items)
lapply(items, mean)
## ==============================================================================
## ==============================================================================
## First create a new variable
## ==============================================================================
species_richness <- sample(200)
## ==============================================================================
## ==============================================================================
## Install and load the appropriate library
## ==============================================================================
install.packages("rlist")
library(rlist)
## ==============================================================================
## ==============================================================================
## Then add it to the `items` list
## ==============================================================================
items <- list.append(items, species_number = species_richness)
items
names(items)
## ==============================================================================Προσθέστε στη λίστα my_first_list ένα διάνυσμα ονόματι number_of_individuals που θα περιέχει 50 τυχαίες τιμές και ονομάστε το (εντός της λίστας) Rodents. Στη συνέχεια υπολογίστε την τυπική απόκλιση κάθε αντικειμένου εντός της λίστας.
number_of_individuals <- sample(50)
my_first_list <- list.append(my_first_list, Rodents = number_of_individuals)
lapply(my_first_list, sd)Η συνηθέστερη μορφή αρχείου που μπορεί να περιέχει δεδομένα τα οποία θέλουμε να εισαγάγουμε στην R είναι αρχεία excel (είτε της μορφής .xlsx είτε της μορφής .csv). Ας δούμε λοιπόν πώς μπορούμε να φορτώσουμε τέτοια αρχεία στην R. Μπορείτε να δείτε στην Εικόνα 4 ένα cheatsheet για την βιβλιοθήκη readr που είναι ιδιαίτερα χρήσιμη για την εισαγωγή αρχείων στην R.
Εικόνα 4. readr cheatsheet
Για να φορτώσουμε ένα αρχείο της μορφής .xlsx θα χρησιμοποιήσουμε την βιβλιοθήκη readxl η οποία αποτελεί τμήμα της βιβλιοθήκης tidyverse:
## =============================================================================
## Let's load an xlsx file
## =============================================================================
## Remember that you need to change the folder path
aegean <- readxl::read_excel("G:/Academic/Lessons/EMB/Labs/Labs/EXCEL/Aegean.xlsx")Για να φορτώσουμε ένα αρχείο της μορφής .csv θα χρησιμοποιήσουμε εντολές από το base installation:
## ==============================================================================
## Let's load a csv file
## ==============================================================================
## Remember that you need to change the folder path
japan <- read.csv("G:/Academic/Lessons/EMB/Labs/Labs/CSV/Ryukyus.csv", h = T,
sep = ";", row.names = 1)
## It's useful to see the help file for this command and get an idea of what
## the different arguments are forΓια να φορτώσουμε ένα αρχείο της μορφής .txt μπορούμε να χρησιμοποιήσουμε τις ακόλουθες εντολές:
## ==============================================================================
## Let's load a txt file
## ==============================================================================
## Base r function
deers <- read.table("G:/Academic/Lessons/EMB/Labs/Labs/TXT/Deer.txt", sep = "\t",
header = T)
## readr library
deers <- readr::read_tsv("G:/Academic/Lessons/EMB/Labs/Labs/TXT/Deer.txt")Φορτώστε τα αρχεία SDM results.xlsx, Temperature.csv και Owls.txt. Το τελευταίο αρχείο φορτώστε το με και τους δύο τρόπους που αναφέραμε προηγουμένως. Ονοματοδοτήστε τα αντικείμενα που περιέχουν τα αρχεία αυτά, cretan_sie, temp και birds, αντίστοιχα.
Εάν θέλουμε τώρα να δούμε πόσα και ποιά αρχεία/αντικείμενα έχουμε φορτώσει στην R, πληκτρολογούμε την ακόλουθη εντολή:
ls()## [1] "aegean" "age" "all_together" "Brand"
## [5] "deers" "diabetes" "digits" "japan"
## [9] "M.user" "patientdata" "patientID" "random_numbers"
## [13] "Soft" "status" "Temp"
Εάν θέλουμε τώρα να αφαιρέσουμε κάποια αρχεία/αντικείμενα που έχουμε φορτώσει στην R, πληκτρολογούμε την ακόλουθη εντολή:
rm(list = ls()) ## Removes everything from R
rm(japan) ## Removes only japanΕάν θέλουμε τώρα να αποθηκεύσουμε κάποια αρχεία/αντικείμενα που έχουμε φτιάξει στην R, πληκτρολογούμε την ακόλουθη εντολή:
## ==============================================================================
## Let's save to an xlsx file
## ==============================================================================
xlsx::write.xlsx(aegean, "./Test data.xlsx")
## ==============================================================================
## ==============================================================================
## Save our data to a csv file
## ==============================================================================
write.csv(aegean, "./Test data.csv")
## ==============================================================================
## ==============================================================================
## Save our data to a txt file
## ==============================================================================
write.table(aegean, "./Test data.txt")
## ==============================================================================Κάποιες φορές όμως, μπορεί το εκάστοτε αντικείμενο να είναι πολύ μεγάλο σε μέγεθος ή να μην είναι συμβατό με το Excel και να χρειάζεται να το αποθηκεύσουμε σε μια άλλη μορφή, εύκολα διαχειρίσιμη τόσο από την R, αλλά και τον Η/Υ μας. Στην περίπτωση αυτή, αποθηκεύουμε το αντικείμενο μας υπό την μορφή .rds αρχείου:
saveRDS(aegean, './Test data.rds)Και εάν θέλουμε να φορτώσουμε ξανά αυτό το αρχείο στην R, τότε γίνεται με την εντολή:
Aegean <- readRDS('./Test data.rds)Αποθηκεύστε στον σκληρό σας δίσκο με κάθε έναν από τους προαναφερθέντες τρόπους το αντικείμενο deers (xlsx, csv, txt & rds) με το πρόθεμα lab κάθε φορά21. Φορτώστε το αρχείο rds που δημιουργήσατε στην R.
Πάρα πολλές φορές θα χρειαστεί να κάνετε κάποιες τροποποιήσεις στα δεδομένα που θα έχετε εισαγάγει/δημιουργήσει στην R. Κάποιες πολύ χρήσιμες βιβλιοθήκες για τον σκοπό αυτό, συμπεριλαμβάνονται εντός της βιβλιοθήκης tidyverse, όπως είναι η βιβλιοθήκη dplyr και η βιβλιοθήκη tidyr (δείτε το cheatsheet τους).
Οι δύο αυτές βιβλιοθήκες επιτρέπουν τον εύκολο μετασχηματισμό των δεδομένων μας (Εικόνα 5)
Εικόνα 5. dplyr & tidyr
Τα βασικά ρήματα είναι τα εξής:
1. select
2. rename
3. filter
4. slice
5. arrange
6. distinct
7. mutate
8. top_n
9. sample_n
10. group
11. summarise
Άλλα χρήσιμα ρήματα είναι τα ακόλουθα:
1. contains
2. ends_with
3. everything
4. starts_with
Όπως διαπιστώνετε η πλειονότητα εξ αυτών στην ουσία δεν χρειάζεται επεξήγηση για το τι κάνουν. Μπορούμε επίσης να χρησιμοποιήσουμε συγχρόνως κάποιους λογικούς κανόνες, όπως οι ακόλουθοι:
1. < Μικρότερο από
2. > Μεγαλύτερο από
3. <= Μικρότερο ή ίσο από
4. >= Μεγαλύτερο ή ίσο από
5. == Ίσο με
6. != Διαφορετικό από
7. & Και
8. | Ή
tidyverse και οι βιβλιοθήκες που περιέχει;Γιατί οι βιβλιοθήκες αυτές είναι ιδιαίτερα χρήσιμες για την τροποποίηση, διερεύνηση και οπτικοποίηση των δεδομένων μας και διέπονται από μια κοινή φιλοσοφία: τα “τακτοποιημένα δεδομένα” (tidy data). Αυτού του τύπου τα δεδομένα έχουν τα εξής χαρακτηριστικά:
1. Κάθε μεταβλητή αποτελεί μια στήλη
2. Κάθε παρατήρηση αποτελεί μια σειρά
3. Κάθε τύπος παρατηρούμενης μονάδας αποτελεί έναν πίνακα
Εικόνα 6. Tidy data
Η Εικόνα 7 απεικονίζει τον μετασχηματισμό κάποιων messy data σε tidy data:
Εικόνα 7. Μετασχηματισμός δεδομένων
Δουλεύοντας με tidy data επικεντρωνόμαστε στο ερευνητικό πρόβλημα που έχουμε να αντιμετωπίσουμε και όχι στα data logistics.
Ας δούμε λοιπόν τι κάνει κάθε μια από τις εντολές που αναφέραμε προηγουμένως, αφού πρώτα φορτώσουμε την κατάλληλη βιβλιοθήκη και τα απαραίτητα δεδομένα:
## ==============================================================================
## Let's start with the dplyr library
## ==============================================================================
library(dplyr)
## ==============================================================================
## ==============================================================================
## Load the data
## ==============================================================================
data(starwars)
## ==============================================================================Θέλουμε να επιλέξουμε τις στήλες name, height και gender. Αυτό επιτυγχάνεται με την εντολή select:
## ==============================================================================
## Column selection
## ==============================================================================
variable_selection <- select(starwars, name, height, gender)
## ==============================================================================
## ==============================================================================
## if we wanted the variables starting with 'h'
## ==============================================================================
variable_selection <- select(starwars, starts_with("h"))
## ==============================================================================
## ==============================================================================
## if we wanted the variables ending with 'r'
## ==============================================================================
variable_selection <- select(starwars, ends_with("r"))
## ==============================================================================
## ==============================================================================
## if we wanted the variables containing 'ol'
## ==============================================================================
variable_selection <- select(starwars, contains("ol"))
## ==============================================================================Εάν τώρα θέλουμε να επιλέξουμε συγκεκριμένες σειρές οι οποίες ικανοποιούν κάποιο κριτήριο, τότε θα χρησιμοποιήσουμε την εντολή filter:
## ==============================================================================
## Row selection
## ==============================================================================
row_selection <- filter(starwars, mass < 70)
row_selection <- filter(starwars, mass > 70 & height < 170)
row_selection <- filter(starwars, height/mass >= 2)
row_selection <- filter(starwars, species == "Droid")
## ==============================================================================Εάν θέλουμε να μετονομάσουμε μια μεταβλητή, τότε θα χρησιμοποιήσουμε την εντολή rename:
## ==============================================================================
## Let's rename the 'mass' variable to 'weight'
## ==============================================================================
col_rename <- rename(starwars, weight = mass)
## ==============================================================================Εάν θέλουμε να επιλέξουμε συγκεκριμένες σειρές (π.χ, την 5η σειρά ή τις σειρές 7-10), τότε θα χρησιμοποιήσουμε την εντολή slice:
## ==============================================================================
## Select the 5th row of your data
## ==============================================================================
row_selection_new <- slice(starwars, 5)
## ==============================================================================
## ==============================================================================
## Select the 7-10 rows of your data
## ==============================================================================
row_selection_new <- slice(starwars, 7:10)
## ==============================================================================
## ==============================================================================
## Select every row except the 5th
## ==============================================================================
row_selection_new <- slice(starwars, -5)
## ==============================================================================
## ==============================================================================
## Select every row except the 7-10 rows
## ==============================================================================
row_selection_new <- slice(starwars, -c(7:10))
## ==============================================================================Εάν θέλουμε να επιλέξουμε/δούμε τις μοναδικές τιμές (μη επαναλαμβανόμενες) σε μια στήλη, τότε θα χρησιμοποιήσουμε την εντολή distinct:
## ==============================================================================
## Retain only the unique rows from the 'species' variable
## ==============================================================================
uniq_species <- distinct(starwars, species)
## ==============================================================================Εάν θέλουμε να δημιουργήσουμε μια νέα μεταβλητή, τότε θα χρησιμοποιήσουμε την εντολή mutate:
## ==============================================================================
## Create a new variable
## ==============================================================================
new_var <- mutate(starwars, height_mass_ratio = mass/height)
## ==============================================================================Εάν θέλουμε να επιλέξουμε τις x υψηλότερες τιμές μιας μεταβλητής, τότε θα χρησιμοποιήσουμε την εντολή top_n:
## ==============================================================================
## Select the 5 tallest individuals
## ==============================================================================
high_rank <- top_n(starwars, 5, height)
## ==============================================================================Εάν θέλουμε να επιλέξουμε x τυχαίες τιμές από ένα σύνολο δεδομένων, τότε θα χρησιμοποιήσουμε την εντολή sample_n:
## ==============================================================================
## Select 10 rows at random
## ==============================================================================
random_sample <- sample_n(starwars, 10)
## ==============================================================================Φορτώστε το αρχείο Aegean.xlsx και ονομάστε το aegean. Στη συνέχεια:
1. Διαλέξτε τις μεταβλητές Island και Endemics
2. Διαλέξτε τις μεταβλητές που ξεκινούν με E
3. Διαλέξτε τις μεταβλητές που τελειώνουν σε s
4. Διαλέξτε τις μεταβλητές που περιέχουν τα γράμματα atu
5. Διαλέξτε τις σειρές όπου η έκταση είναι μικρότερη από 50 km2
6. Διαλέξτε τις σειρές όπου η βροχόπτωση (Rainfall) είναι μεγαλύτερη από 600 και τα Αιγαιακά ενδημικά (Aegean_endemics) λιγότερα από 15
7. Διαλέξτε τις σειρές όπου η βροχόπτωση (Rainfall) είναι μεγαλύτερη από 600 ή τα Αιγαιακά ενδημικά (Aegean_endemics) περισσότερα από 45
8. Διαλέξτε τις σειρές όπου η βιογεωγραφική περιοχή (Region) είναι αυτή της Πελοπονήσσου (Pe)
9. Μετονομάστε τη μεταβλητή Distance_Mainland σε DM
10. Επιλέξτε μόνο τη σειρά 23
11. Επιλέξτε τις σειρές 48 έως 54
12. Επιλέξτε όλες τις σειρές εκτός των σειρών 5 έως 12
13. Πόσοι είναι οι διαφορετικοί πλανήτες (homeworld) που περιλαμβάνει το αντικείμενο starwars; 14. Πόσες είναι οι βιογεωγραφικές περιοχές (Region) του Αιγαίου;
15. Δημιουργήστε μια νέα μεταβλητή στο αντικείμενο aegean ονόματι Temp_range και η οποία θα είναι ίση με \[\Delta(Max_Temperature - Min_Temperature)\]
16. Επιλέξτε τις 8 υψηλότερες τιμές του αντικειμένου aegean
17. Επιλέξτε 20 τυχαίες σειρές του αντικειμένου aegean
##-------------------------
## The solution
##-------------------------
## Remember that you need to change the folder path
aegean <- readxl::read_excel("G:/Academic/Lessons/EMB/Labs/Labs/Aegean.xlsx")
aegean_selection <- select(aegean, Island, Endemics)
aegean_selection <- select(aegean, starts_with("E"))
aegean_selection <- select(aegean, ends_with("s"))
aegean_selection <- select(aegean, contains("atu"))
aegean_selection <- filter(aegean, Area < 50)
aegean_selection <- filter(aegean, Rainfall > 600 & Aegean_endemics < 15)
aegean_selection <- filter(aegean, Rainfall > 600 | Aegean_endemics > 45)
aegean_selection <- filter(aegean, Region == "Pe")
aegean_selection <- rename(aegean, DM = Distance_Mainland)
aegean_selection <- slice(aegean, 23)
aegean_selection <- slice(aegean, 48:54)
aegean_selection <- slice(aegean, -c(5:12))
planets <- distinct(starwars, homeworld)
regions <- distinct(aegean, Region)
new_var <- mutate(aegean, Temp_range = Max_Temperature - Min_Temperature)
high_rank <- top_n(aegean, 8)
random_rows <- sample_n(aegean, 20)Πιθανόν να έχετε διαπιστώσει ότι ίσως να υπάρχει ένας άλλος, πιο γρήγορος, καθαρός και ξεκούραστος τρόπος να γράφει κάποιος κώδικα. Και δεν θα έχετε άδικο. Με το σύμβολο %>% από την βιβλιοθήκη magrittr, μας δίνεται η δυνατότητα μέσα σε λίγες σειρές κώδικα να αυτοματοποιήσουμε και απλοποιήσουμε κάποιες διαδικασίες22. Επί παραδείγματι, ας υποθέσουμε ότι θέλουμε να διαλέξουμε κάποιες μεταβλητές από το το αντικείμενο starwars, να δημιουργήσουμε μια νέα μεταβλητή, να διαλέξουμε συγκεκριμένες σειρές και να τις ταξινομίσουμε κατά αύξουσα σειρά. Εάν δεν χρησιμοποιήσουμε το προαναφερθέν σύμβολο, τότε ο κώδικας μας θα ήταν αρκετά πιο μεγάλος και πιο επιρρεπής σε λάθη. Ας το δούμε στην πράξη:
starwars_pp <- starwars %>%
## Let's select some variables
select(name, height, mass, homeworld, species) %>%
## Then create one new variable
mutate(BMI = mass/(height/100)^2) %>%
## Then select only those rows that refer to humans
filter(species == "Human") %>%
## Finally, arrange the rows to BMI descending order
arrange(desc(BMI))Φορτώστε (εάν δεν το έχετε κάνει ήδη) το αρχείο Aegean.xlsx και ονομάστε το aegean. Στη συνέχεια, δημιουργήστε με αλυσιδωτές εντολές ένα αντικείμενο το οποίο θα περιέχει:
1. τις μεταβλητές Island, Area, Endemics, Temperature, LGM_Temp, Rainfall, SES_PBD_End
2. δύο νέες μεταβλητές, τις Log_Endemics και Perc_Temp_Change. Η πρώτη αποτελεί τον λογάριθμο (10) της μεταβλητής Endemics, ενώ η δεύτερη ορίζεται ως \[\frac{Temperature - LGM_Temp}{Temperature}\]
3. μόνο τα νησιά με έκταση μεγαλύτερη από 100 km2
4. και θα είναι ταξινομημένα κατά μειούμενο μέγεθος
##-------------------------
## The solution
##-------------------------
aegean <- readxl::read_excel("G:/Academic/Lessons/EMB/Labs/Labs/Aegean.xlsx")
aegean <- aegean %>% select(Island, Area, Endemics, Temperature, LGM_Temp, Rainfall,
SES_PBD_End) %>% mutate(Log_Endemics = log10(Endemics), Perc_Temp_Change = (Temperature -
LGM_Temp)/Temperature) %>% filter(Area > 100) %>% arrange(desc(Area))Μπορεί να θέλουμε να ομαδοποιήσουμε τα δεδομένα μιας μεταβλητής σύμφωνα με μια άλλη23, προκειμένου να εξάγουμε κάποια στατιστικά στοιχεία. Αυτό γίνεται ως εξής:
starwars_grp <- starwars %>% group_by(homeworld)Κάντε το ίδιο για την μεταβλητή species, αλλά και για την μεταβλητή Region από το αντικείμενο aegean που έχετε δημιουργήσει σε προηγούμενο βήμα.
##-------------------------
## The solution
##-------------------------
starwars_grp <- starwars %>% group_by(species)
aegean_grp <- aegean %>% group_by(Region)Αφού έχουμε ομαδοποιήσει τα δεδομένα μας, θέλουμε να δημιουργήσουμε ένα νέο αρχείο το οποίο θα περιέχει κάποια βασικά στατιστικά στοιχεία για τις διάφορες κατηγορίες που μας ενδιαφέρουν.
starwars_grp <- starwars %>% mutate(BMI = mass/(height/100)^2) %>% group_by(species) %>%
summarise(max_BMI = max(BMI), min_BMI = min(BMI), mean_BMI = mean(BMI),
median_BMI = median(BMI), SD_BMI = sd(BMI), Count = n()) %>% filter(Count >
1)Όπως μπορείτε να διαπιστώσετε, για την πλειονότητα των ειδών δεν μπορούμε να εξάγουμε σωστά στατιστικά στοιχεία, διότι εμφανίζονται οι τιμές NA και NaN.
Αυτό συμβαίνει διότι πολλές φορές τα δεδομένα που έχουμε διαθέσιμα δεν είναι ολοκληρωμένα.
Μπορεί να υπάρχουν τιμές οι οποίες δεν είναι γνωστές (NA: Not Available) ή οι οποίες δεν αποτελούν αριθμό (NaN: Not a Number).
Η R μπορεί να χειρίζεται αρκετά καλά τέτοιου είδους δεδομένα.
Μπορούμε να δούμε ποιές σειρές δεν περιέχουν δεδομένα με την εντολή is.na() και να διαλέξουμε μόνο τις σειρές που περιέχουν δεδομένα με την εντολή !is.na().
Χρήσιμη εντολή είναι η drop_na() η οποία αφαιρεί όλες τις σειρές χωρίς δεδομένα.
Τέλος, κάποιες εντολές περιέχουν την επιλογή na.rm = T μέσω της οποίας δεν αφαιρούνται οι σειρές χωρίς δεδομένα, αλλά δεν λαμβάνονται υπ’όψιν για τον υπολογισμό κάποιων στατιστικών στοιχείων.
Ας το δούμε στην πράξη:
## ==============================================================================
## First let's check which rows DON'T have data for the variable 'mass'
## ==============================================================================
starwars_na_mass <- starwars %>% filter(is.na(mass))
## ==============================================================================
## ==============================================================================
## Then let's check which rows have data for the same variable
## ==============================================================================
starwars_with_mass <- starwars %>% filter(!is.na(mass))
## ==============================================================================
## ==============================================================================
## As a third step, let's use the na.rm argument inside each command
## ==============================================================================
starwars_grp_narm <- starwars %>% mutate(BMI = mass/(height/100)^2) %>% group_by(species) %>%
summarise(max_BMI = max(BMI, na.rm = T), min_BMI = min(BMI, na.rm = T),
mean_BMI = mean(BMI, na.rm = T), median_BMI = median(BMI, na.rm = T),
SD_BMI = sd(BMI, na.rm = T), Count = n()) %>% filter(Count > 1)
## ==============================================================================
## ==============================================================================
## As a final step, let's use the drop_na() command
## ==============================================================================
starwars_grp_drop <- starwars %>% mutate(BMI = mass/(height/100)^2) %>% group_by(species) %>%
drop_na(mass) %>% summarise(max_BMI = max(BMI), min_BMI = min(BMI), mean_BMI = mean(BMI),
median_BMI = median(BMI), SD_BMI = sd(BMI), Count = n()) %>% filter(Count >
1)
## ==============================================================================Φορτώστε το αρχείο Deer.txt. Έλεγξτε ποιές μεταβλητές δεν περιέχουν δεδομένα και πόσες σειρές δεν έχουν δεδομένα. Μετατρέψτε την μεταβλητή Farm σε factor. Πόσα και ποιά είναι τα επίπεδα της; Κάντε το ίδιο για την μεταβλητή Sex. Στη συνέχεια, ομαδοποιήστε τα δεδομένα σας σύμφωνα με την μεταβλητή Farm και υπολογίστε τις ακόλουθες στατιστικές ιδιότητες για την μεταβλητή LCT: max, min, mean, median, sd & count, χωρίς να λάβετε υπ’όψιν τις σειρές που δεν έχουν δεδομένα. Ακολούθως, κρατήστε μόνο τις φάρμες με περισσότερα από 40 άτομα. Τέλος, ταξινομήστε τις φάρμες κατά μειούμενη σειρά της μεταβλητής που περιέχει τον διάμεσο τη LCT.
##-------------------------
## The solution
##-------------------------
## Remember to change the folder path
deers <- readr::read_tsv("G:/Academic/Lessons/EMB/Labs/Labs/TXT/Deer.txt")
deers %>% filter(is.na(Tb))
deers %>% filter(is.na(KFI))
deers$Farm <- factor(deers$Farm)
deers$Sex <- factor(deers$Sex)
nlevels(deers$Farm)
deers_grp <- deers %>% group_by(Farm) %>% summarise(max_LCT = max(LCT, na.rm = T),
min_LCT = min(LCT, na.rm = T), mean_LCT = mean(LCT, na.rm = T), median_LCT = median(LCT,
na.rm = T), SD_LCT = sd(LCT, na.rm = T), Count = n()) %>% filter(Count >
40) %>% arrange(desc(median_LCT))Ο όρος βιβλιοθήκη (library) χρησιμοποιείται όταν φορτώνουμε ένα πακέτο (package) στην R, αλλά και όταν αναφερόμαστε στο πακέτο αυτό καθ’αυτό. Από εδώ και στο εξής θα αναφερόμαστε στα packages ως βιβλιοθήκες↩
Η συντριπτική πλειοψηφία των βιβλιοθηκών παρέχουν παραδείγματα για το πώς μπορεί κάποιος να χρησιμοποιήσεις τις εντολές που περιέχουν↩
Όπως έχουμε κάνει εμείς σήμερα↩
Δηλαδή, το πλήρες μονοπάτι (path) είναι G:/Academic/Lessons/EMB/Labs/Labs στον δικό μου Η/Υ. Στον δικό σας ποιό είναι;↩
Ο φάκελος στον οποίο βρίσκονται όλα τα αρχεία του project μας και στον οποίο αποθηκεύονται ότι αρχεία δημιουργούμε εντός της R↩
Για πολλούς και διαφορετικούς λόγους: π.χ., έχουμε γράψει κάτι με λάθος όνομα↩
Καθώς με την παρόδο του χρόνου θα έχουμε αποκτήσει μεγαλύτερη εμπειρία με την R και θα είμαστε πιο ψύχραιμοι όσον αφορά τις αντιδράσεις μας↩
Θα αντιληφθείτε σε λίγο γιατί↩
Εάν κάποιος από εσάς θέλει να εμβαθύνει, ας κοιτάξει αυτόν τον σύνδεσμο↩
Φαίνεται από το γεγονός ότι έχουν εισαγωγικά↩
Μπορούμε να δούμε τα ονόματα τους με τις εντολές row.names(mymatrix) και colnames(mymatrix). Όπως θα παρατηρήσετε, είναι κενά.↩
Hint: Χρησιμοποιήστε την εντολή sort() για να το πετύχετε αυτό↩
Hint: row.names(my_second_matrix) <- paste0("Site_", 1:25) για τις σειρές και colnames(mymatrix) <- paste0("Species_", 1:8) για τις στήλες↩
dim()↩
apply(my_third_matrix, 2, log)↩
apply(my_third_matrix, 2, range) και apply(my_third_matrix, 1, range), αντίστοιχα↩
my_fourth_matrix <- my_third_matrix[c(4:8, 17:21),]↩
ο πίνακας (dataframe) ή η παραλλαγή του το tibble είναι ο άλλος↩
Με την εντολή vector μπορούμε να δημιουργήσουμε και ένα άδειο διάνυσμα, οποιασδήποτε μορφής και μήκους (π.χ., vector('numeric', 24)↩
Από την βιβλιοθήκη rlist↩
Δηλαδή, lab.xlsx, lab.csv, lab.txt & lab.rds↩
Το εν λόγω σύμβολο μπορείτε να το προσθέσετε στον κώδικα σας εάν πατήσετε στο R-Studio Shift + Ctl + M↩
Η ομαδοποιούσα μεταβλητή πρέπει να είναι ποιοτική↩